﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Oxage.Windows.Controls;

namespace Oxage.Models
{
	public class ConsoleViewModel : INotifyPropertyChanged
	{
		#region Constructor
		public ConsoleViewModel()
		{
		}
		#endregion

		#region Public properties
		/// <summary>
		/// Gets all ICommandLineHandler types from this assembly.
		/// </summary>
		public List<CommandLineHandlerAttribute> CommandLineHandlers
		{
			get
			{
				if (commandLineHandlers == null)
				{
					commandLineHandlers = new List<CommandLineHandlerAttribute>();

					//Get all ICommandLineHandler types from this assembly
					var types = this.GetType().Assembly.GetTypes().Where(x => typeof(ICommandLineHandler).IsAssignableFrom(x) && !x.IsAbstract).ToList();
					foreach (var type in types)
					{
						var attributes = Attribute.GetCustomAttributes(type).OfType<CommandLineHandlerAttribute>();
						foreach (var attribute in attributes)
						{
							attribute.Type = type;
							commandLineHandlers.Add(attribute);
						}
					}
				}
				return commandLineHandlers;
			}
		}
		private static List<CommandLineHandlerAttribute> commandLineHandlers = null;
		#endregion

		#region Public methods
		public void HandleCommand(IConsole console, CommandLineEventArgs e)
		{
			//if (string.IsNullOrWhiteSpace(e.Command))
			if (string.IsNullOrEmpty(e.Command))
			{
				//Quietly ignore empty command
				return;
			}

			//Find and command and run it
			var attribute = this.CommandLineHandlers.FirstOrDefault(x => x.Command == e.Command);
			if (attribute != null)
			{
				var handler = Activator.CreateInstance(attribute.Type) as ICommandLineHandler;
				handler.Run(console, e.Line, e.Command, e.Arguments);
			}
			else
			{
				console.WriteLine("Unknown command: " + e.Command);
				//console.WriteLine("Type 'help' for more info.");
			}
		}
		#endregion

		#region INotifyPropertyChanged Members
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		#endregion
	}
}
